<template>
	<div class="user">
		<div class="contentMain">
			<div class="title">
				<span>角色管理</span>
			</div>
			<div class="main">
				<div class="main-right" ref="mainRight">
					<div class="searchValue">
						<div class="leftBtn">
							<el-input
								placeholder="用户名 / 昵称"
								size="mini"
								v-model="searchValue">
								<i slot="prefix" class="el-input__icon el-icon-Ssearch"></i>
							</el-input>
							<el-button v-for="(v,i) in headerBtn" :key="i" :type="v.type" :loading="loading" :icon="v.icon" size="mini" @click="handClick(i)">{{ v.title }}</el-button>
						</div>
						<div class="rightBtn">
							<el-button v-for="(v,i) in headerBtnbottomRight" :key="i" :type="v.type" :loading="loading" :icon="v.icon" size="mini" @click="AddhandClick(i)">
								<span v-if="v.title">{{ v.title }}</span>
							</el-button>
						</div>
					</div>
					<div class="content">
						<el-table 
						  :data="showCheckResult ? [checkResult] : tableData" 
						  :header-cell-style="{ background: '#f4f4f4 !important', border: '1px solid #ebeef5' }"
						  :cell-style="{ border: '1px solid #ebeef5' }"
						  border 
						  @row-dblclick="handledbRow"
						  style="width: 100%"
						  :row-class-name="tableRowClassName" 
						  ref="table"
						>
							<el-table-column prop="clinicId" label="当前诊所" width="99">
								 <template slot-scope="{ row }">
									<!-- 根据state显示不同的内容 -->
									<span>{{ docclinicMap[row.clinicId] || '' }}</span>
								</template>
							</el-table-column>
							<el-table-column v-for="(col, inx) in tableRows" :key="inx" border='false' :type="col.type" :prop="col.prop" :label="col.name" :width="columnWidth(col, tableData)"></el-table-column>
							<!-- fixed -->
							<el-table-column fixed="left" label="序号" type="index"></el-table-column>
							<!-- edit -->
							<el-table-column fixed="right" label="操作" width="148">
								<template slot-scope="scope">
								  <div class="editbox" style="display: flex;justify-content: center;">
									  <el-link style="margin-left:12px;font-size:12px;" size="mini" @click="handleEdit(scope.row)">编辑</el-link>
									  <!-- <el-link style="margin-left:12px;font-size:12px;" size="mini" >新增</el-link> -->
									  <el-link style="margin-left:12px;font-size:12px;" size="mini" type="danger" @click="handleDelete(scope.row.id)">删除</el-link>
								  </div>
								</template>
							</el-table-column>
						</el-table>
					</div>
					<div class="foot">
						<!-- 分页 -->
						<el-pagination
						@size-change="handleSizeChange"
						@current-change="handleCurrentChange"
						:current-page="pageNum"
						:page-sizes="[10, 50, 100]"
						:page-size="pageSize"
						:total="totalSize"
						layout="total, sizes, prev, pager, next, jumper"
						background
						>
						</el-pagination>
					</div>
					<!-- 新增Model -->
					<div class="addModel">
						<el-dialog title="新增角色" :visible.sync="addRoleDialog" width="28%" :before-close="handleClose">
							<el-form ref="addForm" :model="addForm" label-width="88px" size="mini">
								<el-form-item label="角色名称">
								<!-- 	<el-select v-model="addForm.roleName" filterable placeholder="placeholder" @focus="checkYNRole" @change="chooseRole">
										<el-option v-for="item in roleOptions" :key="item.label" :label="item.label" :value="item.id" :disabled="item.disabled"> 
										<span style="float: center; color: #8492a6; font-size: 12px">{{ item.label }}</span></el-option>
									</el-select> -->
									<el-select
									  v-model="addForm.roleName"
									  placeholder="请输入 / 选择角色名称"
									  size="mini"
									  filterable
									  allow-create
									  clearable
									  style="width: 100%"
									>
									  <el-option
									    v-for="item in refundReasons"
									    :key="item.id"
									    :label="item.value"
									    :value="item.value"
									  ></el-option>
									</el-select>
								</el-form-item>
								<el-form-item label="角色编码">
									<el-input v-autoCode="addForm.roleCode" v-model="addForm.roleCode" placeholder="请输入内容"></el-input>
								</el-form-item>
								<el-form-item label="当前诊所" v-if="this.clinicId === 0">
									<el-select v-model="addForm.clinicId" placeholder="请选择" collapse-tags>
									  <el-option v-for="item in clincOptions" :key="item.label" :label="item.label" :value="item.id"></el-option>
									</el-select>
								</el-form-item>
								<!-- 保持true以不允许父子关联 -->
								<el-form-item label="菜单权限">
									<el-tree
									  :data="MenuData"
									  show-checkbox
									  node-key="id"
									  :default-expanded-keys="defaultExpandedKeys"
									  :default-checked-keys="defaultCheckedKeys"
									  :check-strictly="true"
									  @check="handleCheck22"
									  @node-contextmenu="handleNodeContextMenu"
									  ref="tree"
									  :props="defaultProps">
									</el-tree>
									  <!-- 在el-tree组件外部添加 -->
									  <div class="context-menu" 
									       v-if="contextMenu.visible" 
									       :style="{left: contextMenu.left + 'px', top: contextMenu.top + 'px'}"
									       @click.stop>
									    <div 
									      class="menu-item" 
									      @click="selectAllChildren()"
									    >
									      全选
									    </div>
									  </div>	
								</el-form-item>
								<el-form-item label="角色备注">
									<el-input v-model="addForm.remark" type="textarea" :rows="4" placeholder="请输入内容"></el-input>
								</el-form-item>
							</el-form>
							<span slot="footer" class="dialog-footer">
							  <el-button type="primary" :loading="addLoading" @click="addSubmit" size="mini">确 定</el-button>
							  <el-button :loading="addLoading" @click="addRoleDialog = false" size="mini">取 消</el-button>
							</span>
						</el-dialog>
					</div>
					<!-- 修改Model  -->
					<div class="editModel">
						<el-dialog title="修改角色" :visible.sync="editRoleDialog" width="28%" :before-close="handleClose">
						    <el-form ref="form" :model="editForm" label-width="88px" size="mini">
						      <el-form-item label="角色名称">
						        <el-input v-model="editForm.roleName" placeholder="请输入内容"></el-input>
						      </el-form-item>
						      <el-form-item label="菜单权限">
						        <el-tree
						          :data="MenuData"
						          show-checkbox
						          node-key="id"
						          :default-expanded-keys="defaultExpandedKeys"
						          :default-checked-keys="defaultCheckedKeys"
						          :check-strictly="true"
						          @check="handleCheck22"
						          @node-contextmenu="handleNodeContextMenu" 
						          ref="tree"
						          :props="defaultProps">
						        </el-tree>
						        <!-- 上下文菜单 -->
						        <div class="context-menu" 
						             v-if="contextMenu.visible" 
						             :style="{left: contextMenu.left + 'px', top: contextMenu.top + 'px'}"
						             @click.stop>
						          <div class="menu-item" @click="selectAllChildren()">全选</div>
						        </div>	
						      </el-form-item>
						    </el-form>
						    <span slot="footer" class="dialog-footer">
						      <el-button :loading="editLoading" type="primary" @click="editSubmit" size="mini">确 定</el-button>
						      <el-button :loading="editLoading" @click="editRoleDialog = false" size="mini">取 消</el-button>
						    </span>
						  </el-dialog>
					</div>
				</div>
			</div>
		</div>
	</div>
</template>

<script>
	import EventBus from '@/untils/event-bus' //EventBus文件路径
	// selfs / sons
	import Pinyin from "@/external/pinyin.js";
	import { getAllRole , AllMenu , editRole , roleMenuIds , deleteRole , addRole , roleList , roleId , checkRole , searchUserMenu } from "@/api/user.js";
	import { docclinic } from "@/api/cinic/cinic.js";
	export default {
		inject: ['reload'], // 无痕刷新
		components: {
			
		},
		data() {
			return {
				filterText:'',
				searchValue: '',
				selectValue: '',
				uName:'',
				loading: false,
				disabled: false,
				addRoleDialog: false,
				editRoleDialog: false,
				windowWidth: '',
				defaultExpandedKeys: [1], // 默认展开的节点 id
				defaultCheckedKeys: [2], // 默认选中的节点 id
				highlightRowId: null, // 用于存储要高亮显示的行的id
				highlightClassName: 'highlight-row', // 高亮行的类名
				pageNum: 1, //当前页currentPage
				pageSize: 10,
				totalSize: 10, //总条数
				defaultProps: {
					children: 'children',
					label: 'label'
				},
				clinicId: null,
				currentEditId: null,
				checkResult: null, // 存储检测结果
				showCheckResult: false, // 是否显示检测结果
				addLoading: false,
				editLoading: false,
				clincOptions:[], // 隶属诊所
				// 添加上下文菜单状态
				contextMenu: {
				  visible: false,
				  left: 0,
				  top: 0,
				  node: null
				},
				
				elTree:[{ label: '宜宾九阵软件科技有限公司', path:'', title:'', icon:'el-icon-news',
					children:[
						{
							label: '运维部',
							path:'',
							title:'',
							icon:'el-icon-news',
							children:[
								{
									label: '运维一组',
									path:'',
									title:'',
									icon:'el-icon-news',
								},
								{
									label: '运维二组',
									path:'',
									title:'',
									icon:'el-icon-news',
								},
								{
									label: '运维三组',
									path:'',
									title:'',
									icon:'el-icon-news',
								},
							]
						},
						{
							label: '后勤部',
							path:'',
							title:'',
							icon:'el-icon-news',
							children:[
								{
									label: '后勤一部',
									path:'',
									title:'',
									icon:'el-icon-news',
								},
								{
									label: '后勤二部',
									path:'',
									title:'',
									icon:'el-icon-news',
								}
							]
						},
						{
							label: '财务部',
							path:'',
							title:'',
							icon:'el-icon-news',
							children:[
								{
									label: '宜宾一部',
									path:'',
									title:'',
									icon:'el-icon-news',
								},
								{
									label: '成都二部',
									path:'',
									title:'',
									icon:'el-icon-news',
								},
								{
									label: '水富三部',
									path:'',
									title:'',
									icon:'el-icon-news',
								}
							]
						},
						{
							label: '研发部',
							path:'',
							title:'',
							icon:'el-icon-news',
							children:[
								{
									label: '后端',
									path:'',
									title:'',
									icon:'el-icon-news',
									children:[
										{
											label: '后端一组',
											path:'',
											title:'',
											icon:'el-icon-news',
										},
										{
											label: '后端二组',
											path:'',
											title:'',
											icon:'el-icon-news',
										}
									]
								},
								{
									label: '前端',
									path:'',
									title:'',
									icon:'el-icon-news',
									children:[
										{
											label: '前端一组',
											path:'',
											title:'',
											icon:'el-icon-news',
										},
										{
											label: '前端二组',
											path:'',
											title:'',
											icon:'el-icon-news',
										}
									]
								},
								{
									label: '设计',
									path:'',
									title:'',
									icon:'el-icon-news',
									children:[
										{
											label: 'UI一部',
											path:'',
											title:'',
											icon:'el-icon-news',
										},
										{
											label: '平面二部',
											path:'',
											title:'',
											icon:'el-icon-news',
										}
									]
								},
							]
						}
					] ,
				}],
				options: [{value: '可用',label: '可用'},{value: '禁用',label: '禁用'}],
				roleOptions:[{id: 0,label: '测试'},{id: 1,label: '普通客户'},{id: 2,label: '超级用户'},{id: 3,label: '管理员'},{id:4,label: '超级管理员'},
				{id: 5,label: '国家医保人员'},{id: 6,label: '运维人员'},{id: 7,label: '医生'},{id: 8,label: '护士'},{id:9,label: '我是老板'},{id:10,label: '内部研发人员'},
				],
				docclinicOptions:[], // 获取诊所列表
				// header查询重置按钮
				headerBtn:[{ title:"检测", icon:"el-icon-refresh" }],
				headerBtnbottomRight:[
					{ title:"新增", icon:"el-icon-plus",type:'primary' },
					{ title:"刷新", icon:"el-icon-refresh",type:'' },
				],
				edits:[{ title:"详情",type:'primary' },{ title:"修改",type:'primary' },{ title:"分配",type:'primary' },{ title:"删除",type:'danger' }],
				// 表格行
				tableRows:[
					{ name:"角色名称", prop:"roleName", type:"" },{ name:"角色ID", prop:"id", type:"" },
					{ name:"角色编码", prop:"roleCode", type:"" },{ name:"描述", prop:"remark", type:"" },
					{ name:"创建时间", prop:"createdTime", type:"" },{ name:'更新时间', prop:'modifyTime', type:''}
				],
				docclinicMap:{},
				// 表格data
				tableData:[],
				refundReasons: [
				  { value: '用户', id: 1 },
				  { value: '护士', id: 2 },
				  { value: '医师', id: 3 },
				  { value: '药房', id: 4 },
				  { value: '管理员', id: 5 },
				  { value: '超级管理员', id: 6 },
				  { value: '其他', id: 7 },
				],
				rrr:[],
				idsArray:[],
				MenuData:[],
				// 新增用户
				addForm:{
					roleName:'', // 角色名称
					roleCode:'', // 角色编码
					menuId:[], // 菜单id 
					remark:'', // 备注
					clinicId:''
				},
				// 修改表单
				editForm:{
					roleName:'', // 角色名称
					id:'', // 角色id
					roleCode:'', // 角色编码
					menuId:[], // 菜单id 
					remark:'', // 备注
					clinicId:''
				},
			}
		},
		async mounted() {
		  // 先加载必要数据
		  await this.getcilinc();
		  await this.getAllMenus();
		  await this.loadData();
		  await this.getInstitutionId();
		  // 其他初始化
		  this.userInfo = JSON.parse(localStorage.getItem('userInfo'));
		  this.clinicId = this.userInfo.clinicId;
		  
		  // 更新窗口宽度
		  this.updateWindowWidth();
		  window.addEventListener('resize', this.updateWindowWidth);
		  
		  // 确保数据加载完成后再执行其他操作
		  this.$nextTick(() => {
		    this.abc();
		    this.getsearchUserMenu();
		  });
		},
		watch: {
		  filterText(val) {
			this.$refs.tree.filter(val);
		  }
		},
		methods:{
			/*
				数据源
			*/
		   
			async loadData() {
			  try {
			    this.loading = true;
			    let res = await getAllRole({
			      pageNum: this.pageNum,
			      pageSize: this.pageSize
			    });
			    
			    if (res.code === 200) {
			      this.tableData = res.data.content || [];
			      this.totalSize = res.data.totalSize || 0;
			      
			      // 确保默认选中第一行（如果需要）
			      if (this.tableData.length > 0) {
			        this.highlightRowId = this.tableData[0].id;
			      }
			    } else {
			      this.$message.error(res.message || '加载数据失败');
			    }
			  } catch (error) {
			    console.error('加载数据出错:', error);
			    this.$message.error('加载数据出错');
			  } finally {
			    this.loading = false;
			  }
			},
			async getcilinc(){
				// 所有菜单
				let res = await docclinic();
				this.docclinicOptions = res.data.map(v=>{ return { label: v.name , ...v }});
				// 将 民族 转换为 minZuMap 格式
				this.docclinicMap = this.docclinicOptions.reduce((map, item) => {
					map[item.id] = item.label;  // 使用 id 作为键，label 作为值
					return map;
				}, { 1: '数据不对，默认null' });  // 保留初始值
			},
			async abc() {
			  let resp = await roleList({
			    clinicId: this.clinicId, // 现在有值了
			  });
			},
			async getsearchUserMenu() {
			  try {
			    this.userInfo = JSON.parse(localStorage.getItem('userInfo'));
			    let uName = this.userInfo.username;
			    
			    // 获取用户菜单
			    let res = await searchUserMenu({
			      username: uName,
			    });
			    console.log(res,'lllllllllllllllllllllllll');
			    // 更新本地存储中的Menus
			    sessionStorage.setItem('Menus', JSON.stringify(res));
			    console.log('用户菜单已更新到本地存储');
			  } catch (error) {
			    console.error('获取用户菜单失败:', error);
			  }
			},
			// 获取赋值隶属机构
			async getInstitutionId(){
				let res = await docclinic();
				this.clincOptions = res.data.map(v=>{ return {label:v.name,...v} });
			},
			async getAllMenus(){
				// 检查会话存储中是否存在 'MenuForRoleItems'
				if (!sessionStorage.getItem('MenuForRoleItems')) {
				  // 如果不存在，则调用所有菜单接口将数据存入会话存储 => 菜单里还未新增之前的数据源存放于会话，以便角色默认使用
				  let res = await AllMenu();
				  this.tableData = res.rows.children;
				  // 将菜单里还未新增之前的数据源存放于会话，以便角色默认使用。
				  sessionStorage.setItem('MenuForRoleItems', JSON.stringify(this.tableData));
				  // console.log('数据已存入会话存储');
				} else {
				  // console.log('数据已存在，未重复存储');
				}
			},
			/*
				about tree
			*/
			handleNodeClick(data,e) {
				this.CatalogueName = data.title
				this.iconComes = 'el-icon-' + this.makePy(data.label)
				console.log(this.iconComes);
				// this.loadData();
			},
			// 检查是否有当前角色
			checkYNRole(){
				// 创建一个 Set 来存储 选择框中 已有的 name
				let namesInB = JSON.parse(localStorage.getItem('userInfo')).roleName
				// 遍历 elMenusOption，判断是否有相同的 name，并新增字段
				this.roleOptions = this.roleOptions.map(item => {
				  if (item.label == namesInB) {
					return { ...item, disabled: true };
				  }
				  return item;
				});
				// console.log(this.roleOptions);
			},
			// 步骤
			handClick(i) {
			  // i event
			  switch (i) {
			    case 0:
			      // 处理索引0的逻辑 - 检测
			      this.handleCheckRole();
			      break;
			  }
			},

			// 新增检测角色方法
			async handleCheckRole() {
			  if (!this.searchValue.trim()) {
			    this.$message.warning('请输入要检测的角色名称');
			    return;
			  }
			
			  try {
			    this.loading = true;
			    const res = await checkRole({ roleName: this.searchValue });
			    
			    if (res.code === 200) {
			      this.checkResult = res.data; // 存储检测结果
			      this.showCheckResult = true; // 显示检测结果
			      
			      if (res.data) {
			        // 查找所有匹配的角色
			        const matchedRows = this.tableData.filter(row => 
			          row.roleName && row.roleName.includes(this.searchValue)
			        );
			        
			        // 显示找到的匹配数量
			        const matchCount = matchedRows.length;
			        this.$message.success(`找到 ${matchCount} 条与"${this.searchValue}"相关的角色数据`);
			        
			        if (matchCount > 0) {
			          // 高亮显示第一个匹配项
			          this.highlightRowId = matchedRows[0].id;
			          
			          // 滚动到高亮行
			          this.$nextTick(() => {
			            const table = this.$refs.table;
			            if (table) {
			              const row = table.$el.querySelector(`.${this.highlightClassName}`);
			              if (row) {
			                row.scrollIntoView({ behavior: 'smooth', block: 'center' });
			              }
			            }
			          });
			        }
			      } else {
			        this.highlightRowId = null;
			        this.$message.warning(`没有找到与"${this.searchValue}"相关的角色数据`);
			      }
			    } else {
			      this.$message.error(res.message || '检测失败');
			    }
			  } catch (error) {
			    console.error('检测角色出错:', error);
			    this.$message.error('检测出错');
			  } finally {
			    this.loading = false;
			  }
			},
			 tableRowClassName({ row }) {
			    return row.id === this.highlightRowId ? this.highlightClassName : '';
			  },
			AddhandClick(i){
				// i event
				switch (i) {
					case 0:
						// 处理索引0的逻辑 新增
						this.addRoleDialog = true;
						this.MenuData = JSON.parse(sessionStorage.getItem('MenuForRoleItems'));
					break;
					case 1:
					// 处理索引0的逻辑 页面刷新
					this.loading = true;
					setTimeout(() => {
						this.reload();
						this.$message({type:'success',message:'已刷新'})
						this.loading = false;		
					}, 1500)
					break;
					case 2:
						// 处理索引1的逻辑
						this.$confirm('敬请期待')
						.then(_ => {})
						.catch(_ => {});
					break;
				}
			},
			// col 里面包含了表头字段和名称，list 是表格数据
			columnWidth(col, list) {
			  let prop = col.prop,lab = col.lab;
			  let width = 80; // 设定一个最小值
			  let maxlenStr = ""; // 最长字符串
			  for (let info of list) {
				if (maxlenStr < (info[prop] + "").length) maxlenStr = info[prop];
			  }
			  width = Math.max(width, len(lab), len(maxlenStr));
			  // 表格自带的内边距(20px) 自调
			  return width + 22; // 这里加了 12px
			  function len(str) {
				// 实际分配长度可根据需要自行调整
				let length = 8;
				for (const char of str + "") {
				  // 英文小写字符 8px
				  if ("a" <= char && char <= "z") length += 18;
				  // 英文大写字符 8px
				  else if ("A" <= char && char <= "Z") length += 18;
				  // 中文字符 28px
				  else if (char >= "\u4e00" && char <= "\u9fa5") length += 42;
				  // 其他 8px
				  else length += 12;
				}
				return length;
			  }
			},
			// 选择角色变化
			chooseRole(val){
				console.log(val);
				this.addForm.roleName = val.label
				this.addForm.roleId = val.id
				this.addForm.id = val.id
			},
			// 确定新增角色 - 添加加载状态
			async addSubmit() {
			  try {
				this.addLoading = true;
				const currentCheckedKeys = this.$refs.tree.getCheckedKeys();
				this.addForm.menuId = currentCheckedKeys;
				this.addForm.roleCode = JSON.parse(sessionStorage.getItem('deptCode'));
				
				this.$refs.addForm.validate(async(valid) => {
				  if (!valid) {
					this.addLoading = false;
					return;
				  }
				  
				  let res = await addRole(this.addForm);
				  if (res.code === 200) {
					this.$message({ type: "success", message: res.message });
					
					// 更新菜单会话存储
					const menuRes = await AllMenu();
					if (menuRes.code === 200) {
					  sessionStorage.setItem('MenuForRoleItems', JSON.stringify(menuRes.data));
					}
					
					this.loadData();
					this.addRoleDialog = false;
					await this.getsearchUserMenu();
					EventBus.$emit('update-menu');
				  } else {
					this.$message({ type: "error", message: res.message });
				  }
				  this.addLoading = false;
				});
			  } catch (error) {
				console.error('新增角色失败:', error);
				this.addLoading = false;
				this.$message.error('新增角色失败');
			  }
			},
			
			// 表格编辑栏
			async handleEdit(row) {
			  this.clinicId = row.id; // 关键赋值
			  this.currentEditId = row.id;
			  this.editRoleDialog = true;
			  this.editForm = {...row}
			  
			  // 取会话菜单
			  this.MenuData = JSON.parse(sessionStorage.getItem('MenuForRoleItems'));
			  
			  // 设置默认选中 - 从接口获取当前角色的菜单权限
			  let res = await roleMenuIds({
			    roleId: row.id
			  });  
			  this.defaultCheckedKeys = res;
			  
			  // 确保树组件使用最新的选中状态
			  this.$nextTick(() => {
			    if (this.$refs.tree) {
			      this.$refs.tree.setCheckedKeys(this.defaultCheckedKeys);
			      // 初始化表单数据
			      this.editForm.menuId = this.defaultCheckedKeys;
			    }
			  });
			  
			  console.log('编辑初始化菜单ID:', this.defaultCheckedKeys);
			},
			
			// 处理复选框变化事件，例如记录选中的节点数据等操作
			handleCheck22(data, { checkedNodes, checkedKeys }) {
			  const tree = this.$refs.tree;
			  
			  // 获取当前选中状态
			  const isChecked = tree.getCheckedKeys().includes(data.id);
			  
			  if (isChecked) {
			    // 勾选时自动勾选所有父节点
			    this.checkParentNodes(tree.getNode(data));
			  } else {
			    // 取消勾选时自动取消所有子节点
			    this.uncheckChildNodes(tree.getNode(data));
			    // 更新父节点状态
			    this.updateParentCheckState(tree.getNode(data));
			  }
			  
			  // 获取最新的选中keys
			  const currentCheckedKeys = tree.getCheckedKeys();
			  
			  // 更新数据绑定
			  this.defaultCheckedKeys = currentCheckedKeys;
			  this.editForm.menuId = currentCheckedKeys;
			  this.addForm.menuId = currentCheckedKeys;
			  
			  console.log('当前选中的菜单ID:', currentCheckedKeys);
			},

			// 添加右键菜单处理方法
			// 修改后的handleNodeContextMenu方法
			handleNodeContextMenu(event, node) {
			  event.preventDefault();
			  event.stopPropagation();
			  
			  // 关闭已打开的菜单
			  this.closeContextMenu();
			  
			  this.contextMenu = {
			    visible: true,
			    left: event.clientX,
			    top: event.clientY,
			    node: node,
			    hasChildren: true // 全选功能总是可用
			  };
			  
			  // 添加事件监听器
			  document.addEventListener('click', this.closeContextMenu);
			  document.addEventListener('contextmenu', this.closeContextMenu);
			},
			
			// 修改后的selectAllChildren方法（现在实现全选功能）
			selectAllChildren() {
			  const tree = this.$refs.tree;
			  if (!tree) return;
			  
			  // 获取整个树的所有节点ID
			  const allKeys = this.getAllKeysFromData(this.MenuData);
			  
			  // 设置选中所有节点
			  tree.setCheckedKeys(allKeys);
			  
			  // 更新表单数据
			  if (this.editRoleDialog) {
			    this.editForm.menuId = allKeys;
			  }
			  if (this.addRoleDialog) {
			    this.addForm.menuId = allKeys;
			  }
			  
			  this.closeContextMenu();
			},
			
			// 新增方法：从树数据中递归获取所有id
			getAllKeysFromData(nodes) {
			  let keys = [];
			  if (!nodes) return keys;
			  
			  nodes.forEach(node => {
			    if (node.id) {
			      keys.push(node.id);
			    }
			    if (node.children && node.children.length > 0) {
			      keys = keys.concat(this.getAllKeysFromData(node.children));
			    }
			  });
			  return keys;
			},
			
			// 关闭菜单
			closeContextMenu() {
			  this.contextMenu.visible = false;
			  document.removeEventListener('click', this.closeContextMenu);
			  document.removeEventListener('contextmenu', this.closeContextMenu);
			},
			
			// 递归获取整个树的所有节点ID
			getAllKeys(node) {
			  let keys = [];
			  // 当前节点
			  if (node.data && node.data.id) {
			    keys.push(node.data.id);
			  }
			  // 递归子节点
			  if (node.childNodes) {
			    node.childNodes.forEach(child => {
			      keys = keys.concat(this.getAllKeys(child));
			    });
			  }
			  return keys;
			},
			    
			 
			// 递归获取所有子节点ID（正确递归获取所有后代节点）
			// 修复后的递归获取所有子节点ID方法
			getAllChildIds(node) {
			  if (!node || !node.data) return [];
			  
			  const ids = [];
			  
			  // 添加当前节点ID
			  if (node.data && node.data.id) {
			    ids.push(node.data.id);
			  }
			  
			  // 递归获取所有子节点
			  const getChildrenIds = (childNode) => {
			    if (!childNode || !childNode.childNodes) return;
			    
			    childNode.childNodes.forEach(child => {
			      if (child && child.data && child.data.id) {
			        ids.push(child.data.id);
			        getChildrenIds(child);
			      }
			    });
			  };
			  
			  getChildrenIds(node);
			  return ids;
			},
			
			
			// 递归勾选父节点
			// 确保checkParentNodes方法也在methods中定义
			  checkParentNodes(node) {
			    if (node.parent) {
			      // 勾选父节点
			      this.$refs.tree.setChecked(node.parent.key, true, false);
			      // 递归勾选所有父节点
			      this.checkParentNodes(node.parent);
			    }
			  },

			 // 确保在methods中定义了updateSessionStorage方法
			  updateSessionStorage() {
			    // 获取当前选中的菜单ID
			    const checkedKeys = this.$refs.tree.getCheckedKeys();
			    
			    // 更新会话存储中的选中状态
			    sessionStorage.setItem('checkedMenuIds', JSON.stringify(checkedKeys));
			  },
			// 递归勾选子节点
			checkChildNodes(node) {
			  if (node.childNodes) {
			    node.childNodes.forEach(child => {
			      this.$refs.tree.setChecked(child.key, true, false); // false表示不触发回调
			      this.checkChildNodes(child);
			    });
			  }
			},
			
			// 递归取消勾选所有子节点
			uncheckChildNodes(node) {
			  if (node.childNodes) {
			    node.childNodes.forEach(child => {
			      this.$refs.tree.setChecked(child.key, false);
			      this.uncheckChildNodes(child);
			    });
			  }
			},
			
			// 更新父节点选中状态
			updateParentCheckState(node) {
			  if (node.parent) {
			    const parentNode = node.parent;
			    const allChildrenUnchecked = parentNode.childNodes.every(
			      child => !this.$refs.tree.getCheckedKeys().includes(child.key)
			    );
			    
			    if (allChildrenUnchecked) {
			      this.$refs.tree.setChecked(parentNode.key, false, false);
			    }
			    
			    this.updateParentCheckState(parentNode);
			  }
			},
			
			updateIndeterminateStates() {
			  const tree = this.$refs.tree;
			  const checkedKeys = tree.getCheckedKeys();
			  
			  // 递归更新所有节点的indeterminate状态
			  const updateNode = (node) => {
			    if (node.childNodes && node.childNodes.length > 0) {
			      const someChecked = node.childNodes.some(child => 
			        checkedKeys.includes(child.key) || child.indeterminate
			      );
			      const allChecked = node.childNodes.every(child => 
			        checkedKeys.includes(child.key)
			      );
			      
			      node.indeterminate = someChecked && !allChecked;
			      
			      // 递归处理子节点
			      node.childNodes.forEach(updateNode);
			    }
			  };
			  
			  tree.root.childNodes.forEach(updateNode);
			},
			
			
			// 显示勾选/取消勾选提示
			showCheckMessage(isChecked, data) {
			  const action = isChecked ? '勾选' : '取消勾选';
			  const relation = isChecked ? '上级菜单已自动勾选' : '所有子菜单已自动取消勾选';
			  
			  this.$message({
			    message: `${action} ${data.label}，${relation}`,
			    type: 'info',
			    duration: 2000
			  });
			},
			// 过滤器
			filterNode(value, data) {
				if (!value) return true;
				return data.label.indexOf(value) !== -1;
			},

			// 删除
			handleDelete(id) {
			  this.$confirm("此操作将永久删除该角色, 是否继续?", "提示", {
			    confirmButtonText: "确定",
			    cancelButtonText: "取消",
			    type: "warning"
			  })
			  .then(async () => {
			    // 用户点击确定，执行删除
			    this.loading = true;
			    try {
			      const result = await deleteRole({ roleId: id });
			      if (result.code === 200) {
			        this.$message.success(result.message);
			        this.loadData(); // 刷新列表
			      } else {
			        this.$message.error(result.message || '删除失败');
			      }
			    } catch (error) {
			      console.error('删除出错:', error);
			      this.$message.error('删除操作出错');
			    } finally {
			      this.loading = false;
			    }
			  })
			  .catch(() => {
			    // 用户点击取消
			    this.$message.info('已取消删除');
			  });
			},
			// 修改提交
			async editSubmit() {
			  try {
				this.editLoading = true;
				const currentCheckedKeys = this.$refs.tree.getCheckedKeys();
				this.editForm.menuId = currentCheckedKeys;
				
				let res = await editRole(this.editForm);
				if (res.code === 200) {
				  this.$message({ type: 'success', message: res.message });
				  
				  const menuRes = await AllMenu();
				  if (menuRes.code === 200) {
					sessionStorage.setItem('MenuForRoleItems', JSON.stringify(menuRes.data));
				  }
				  
				  await this.getsearchUserMenu();
				  EventBus.$emit('update-menu');
				  this.editRoleDialog = false;
				  this.reload();
				} else {
				  this.$message.error(res.message || '修改失败');
				}
			  } catch (error) {
				console.error('编辑角色失败:', error);
				this.$message.error('编辑角色失败');
			  } finally {
				this.editLoading = false;
			  }
			},
			
			// db events
			handledbRow(row, column, event){
				console.log(row);
			},
			//分页
			//每页条数改变触发
			handleSizeChange(val) {
				console.log(`每页 ${val} 条`);
				this.pageNum = val;
				this.loadData();
			},
			//当前条数改变触发
			handleCurrentChange(val) {
				console.log(`当前页: ${val}`);
				this.pageNum = val;
				this.loadData();
			},
			handleClose(done) {
				done();
				this.reload();
			},
			//重置表单
			resetForm(){
				this.$refs.addForm.resetFields();
			},
			// 实时宽度
			updateWindowWidth() {
			    this.windowWidth = window.innerWidth - 228;
			},
			/*
				others
			*/
		    // 定义一个递归函数来提取所有 id
		    extractIds(data) {
		      const ids = []; // 用于存储所有 id 的数组
		    
		      // 递归函数
		      function traverse(node) {
		        if (node.id) {
		          ids.push(node.id); // 添加当前节点的 id
		        }
		    
		        if (node.children && node.children.length > 0) {
		          node.children.forEach(child => {
		            traverse(child); // 递归处理子节点
		          });
		        }
		      }
		    
		      // 遍历根节点
		      data.forEach(node => {
		        traverse(node);
		      });
		    
		      return ids;
		    },
		    // 递归三级children
		    replaceKey(obj) {
		      if (Array.isArray(obj)) {
		        return obj.map(item => this.replaceKey(item));
		      } else if (typeof obj === 'object' && obj !== null) {
		        const newObj = { ...obj };
		        if (newObj.name !== undefined) {
		          newObj.label = newObj.name;
		          delete newObj.name;
		        }
		        for (const key in newObj) {
		          if (typeof newObj[key] === 'object' && newObj[key] !== null) {
		            newObj[key] = this.replaceKey(newObj[key]);
		          }
		        }
					return newObj;
		      } else {
					return obj;
		      }
		    },
			
		},
		watch: {
		    windowWidth(newVal) {
		      console.log('New window width:', newVal);
		      // 在这里执行逻辑，例如重新布局等。
		    }
		}
	}
</script>

<style lang="less" scoped>
	.user{
		width: 100%;
		height: 100%;
		background-color: #fff;
		.contentMain{
			
			.context-menu {
			  position: fixed;
			  z-index: 9999;
			  background: #fff;
			  border: 1px solid #dcdfe6;
			  border-radius: 4px;
			  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
			  padding: 5px 0;
			  min-width: 150px;
			  white-space: nowrap;
			  
			  .menu-item {
			    padding: 8px 15px;
			    cursor: pointer;
			    font-size: 13px;
			    
			    &:hover {
			      background-color: #f5f7fa;
			      color: #409EFF;
			    }
			    
			    &.disabled {
			      color: #c0c4cc;
			      cursor: not-allowed;
			      pointer-events: none;
			    }
			  }
			}
			.title{
				height: 40px;
				line-height: 40px;
				span{
					font-weight: 300;
					margin-left: 12px;
				}
			}
			.main{
				width: 100%;
				margin-top: 8px;
				display: flex;
				.main-right{
					margin-left: 12px;
					.searchValue{
						display: flex;
						justify-content: space-between;
						/deep/ .el-input{
							width: 188px;
						}
						/deep/ .el-select{
							margin-left: 8px;
						}
						/deep/ .el-button{
							margin-left: 8px;
						}
						.leftBtn{
							// display: flex;
							// justify-content: space-around;
						}
					}
					.content{
						display: flex;
						justify-content: center;
						height: 430px;
						width: 100%;
						margin-top: 12px;
						border: 1px solid #dddddd;
						border-radius: 4px;
						/deep/ .el-table .cell{
							font-size: 12px;
							text-align: center;
						}
						/deep/ .el-table--border .el-table__cell, .el-table__body-wrapper .el-table--border.is-scrolling-left~.el-table__fixed{
							border: 0;
						}
						/deep/ .el-table{
							background-color: #fff;
						}
						/deep/ td {
							padding: 0!important;
							height: 32px;
						}
						/deep/ .el-table td.el-table__cell div :first-child{
							text-align: center;
						}
						
					}
					.foot{
						display: flex;
						justify-content: flex-end;
						margin-top: 8px;
					}
				}
			}
		}
	}
</style>